package com.minis.beans.factory.xml;

import com.minis.beans.factory.DefaultListableBeanFactory;
import com.minis.beans.factory.config.*;
import com.minis.beans.factory.AutowiredBeanFactory;
import com.minis.core.ClassPathXmlResource;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.List;

/**
 * 将解析好的 Xml 加载到 BeanFactory
 */
public class XmlBeanDefinitionReader {
//    // simple
//    SimpleBeanFactory beanFactory;
//    // autowired
//    AutowiredBeanFactory beanFactory;
    DefaultListableBeanFactory beanFactory;
//    // simple
//    public XmlBeanDefinitionReader(SimpleBeanFactory beanFactory) {
//        this.beanFactory = beanFactory;
//    }
//    // autowired
//    public XmlBeanDefinitionReader(AutowiredBeanFactory beanFactory) {
//        this.beanFactory = beanFactory;
//    }
    public XmlBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
    public void loadBeanDefinitions(ClassPathXmlResource resource) {
        while (resource.hasNext()) {
            Element element = (Element) resource.next();
            String beanID = element.attributeValue("id");
            String beanClassName = element.attributeValue("class");
            BeanDefinition beanDefinition = new BeanDefinition(beanID, beanClassName);


            // 处理构造器参数
            List<Element> constructorElements = element.elements("constructor-arg");
            ArgumentValues AVS = new ArgumentValues();
            for (Element e : constructorElements) {
                String aType = e.attributeValue("type");
                String aName = e.attributeValue("name");
                String aValue = e.attributeValue("value");
                AVS.addArgumentValue(new ArgumentValue(aType, aName, aValue));
            }
            beanDefinition.setConstructorArgumentValues(AVS);


            // 处理属性
            List<Element> propertyElements = element.elements("property");
            PropertyValues PVS = new PropertyValues();
            List<String> refs = new ArrayList<>();
            for (Element e : propertyElements) {
                String pType = e.attributeValue("type");
                String pName = e.attributeValue("name");
                String pValue = e.attributeValue("value");
                String pRef = e.attributeValue("ref");
                String pV = "";
                boolean isRef = false;
                if (pValue != null && !pValue.equals("")) {
                    pV = pValue;
                } else if (pRef != null && !pRef.equals("")) {
                    isRef = true;
                    pV = pRef;
                    refs.add(pRef);
                }
                PVS.addPropertyValue(new PropertyValue(pType, pName, pV, isRef));
            }
            beanDefinition.setPropertyValues(PVS);

            String[] refArray = refs.toArray(new String[0]);
            beanDefinition.setDependsOn(refArray);

            this.beanFactory.registerBeanDefinition(beanID, beanDefinition);

        }
    }
}
